home *** CD-ROM | disk | FTP | other *** search
/ The X-Philes (2nd Revision) / The X-Philes Number 1 (1995).iso / xphiles / hp48hor1 / ceigen.src < prev    next >
Text File  |  1991-07-24  |  12KB  |  336 lines

  1. %%HP: T(3)A(R)F(.);
  2. @ Author: Ted A Smith
  3. @ Date: Sun July 21, 1991
  4. @
  5. @   Here is my second cut at EigenValue/EigenVector decomposition
  6. @ which is not restricted to real symmetric input matricies.  These
  7. @ routines have been optimized (and accuracy improved) compared to my
  8. @ first try dated Jul 18 1991.
  9. @
  10. @ Checksum of this directory on the stack:  #2B90h, size 2982.5
  11. @ Checksum with only Eigen, EFn1 and EFn2:  #F1BBh, size 1103.5
  12. @
  13. @   The general eigenvalue/eigenvector problem is hard and there are
  14. @ many posible pathologies if the input matrix is not real symmetric.
  15. @ (For theory and examples see the references below.)
  16. @
  17. @ The directory consists of 3 main routines:
  18. @
  19. @   Eigen   Given M returns V and D, where V are the eigenvectors
  20. @             and D are the eigenvalues
  21. @   EFn1    Given M and f returns f(M) defined by V*f(D)*V^-1
  22. @   EFn2    Given V, D and f returns V*f(D)*V^-1
  23. @
  24. @ For example, in analogy with SIN(x)^2+COS(x)^2=1:
  25. @
  26. @   A Eigen DUP2 \<< SIN \>> EFn2 DUP *
  27. @   ROT ROT \<< COS \>> EFn2 DUP * + A IDN - ABS
  28. @
  29. @ will return a small number for almost any square input matrix A.
  30. @
  31. @ Eigen also displays the matrix after each rotation if user flag 1 is
  32. @ set.  Two comments in the code indicate which lines to delete if this
  33. @ feature is not desired.
  34. @
  35. @ There are two test routines:
  36. @
  37. @   Tst     Calculate ABS(DET(M-D*I)) and ABS(M-EFn1(M, \<< \>>))
  38. @   Tst1    Apply SIN(x)^2+COS(x)^2=1 test to a random matrix.
  39. @
  40. @ There are 9 example matricies A, B, C, D, E, F, G, H and J as well as
  41. @ the 3x3 identity matrix I.  The comments in the code give the true
  42. @ eigenvalues for some of these matricies.
  43. @
  44. @ Here following is the theory of operation:
  45. @
  46. @   The QR algorithm is, in theory, a better method; but it is much
  47. @ more complicated.  The virtue of this implementation is its simplicity.
  48. @ It is based on the Jacobi method, which uses trignometric rotations to
  49. @ succesively zero the off-diagonal elements of the input matrix.  When
  50. @ the off-diagonal elements are close enough to zero the diagonal
  51. @ elements approximate the eigenvalues of the original matrix.  In
  52. @ addition, accumulating the product of the rotations gives the matrix of
  53. @ eigenvalues.  On real symmetric matricies the Jacobi method is
  54. @ idiotproof.
  55. @
  56. @   I have extended the algorithm by using hyperbolic "rotations" to
  57. @ drive the off-diagonal elements tword each other, thereby allowing the
  58. @ trignometric transform to be more effective.  I have no proof that this
  59. @ converges!  I have not been able to find a reference for this method.
  60. @ The idea of using hyperbolic transforms was inspired by chapter 17 of
  61. @ reference 3, but this implementation bears no other obvious similarity.
  62. @
  63. @ To illustrate the method let's apply it to the 2 x 2 matrix:
  64. @
  65. @   [[a b]
  66. @    [c d]]
  67. @
  68. @ The standard Jacobi rotation is:
  69. @
  70. @   [[ cos(t) sin(t) ]  [[a b]  [[ cos(t) -sin(t) ]
  71. @    [-sin(t) cos(t) ]]  [c d]]  [ sin(t)  cos(t) ]]
  72. @
  73. @ where t=ATAN((b+c)/(a-d))/2.
  74. @
  75. @ For real a, c and d and b=c this returns:
  76. @
  77. @  /  a+d+SQRT(amd^2+4*c^2)*SIGN(amd)                                \
  78. @  | --------------------------------              0                 |
  79. @  |                2                                                |
  80. @  |                                 a+d-SQRT(amd^2+4*c^2)*SIGN(amd) |
  81. @  |                0                ------------------------------- |
  82. @  \                                               2                 /
  83. @
  84. @ where amd=a-d.
  85. @
  86. @ To drive the off-diagonal elements together we will first apply the
  87. @ hyperbolic transform:
  88. @
  89. @   [[ cosh(t) sinh(t) ]  [[a b]  [[ cosh(t) -sinh(t) ]
  90. @    [ sinh(t) cosh(t) ]]  [c d]]  [-sinh(t)  cosh(t) ]]
  91. @
  92. @ Where t=ATANH((b-c)/(a-d))/2.
  93. @
  94. @ Once again, for real inputs (with fortunate signs) this returns:
  95. @
  96. @  / a+d+SQRT(amd-bmc)*SQRT(amd+bmc)                b+c              \
  97. @  | -------------------------------               -----             |
  98. @  |                 2                               2               |
  99. @  |                                                                 |
  100. @  |                b+c              a+d-SQRT(amd-bmc)*SQRT(amd+bmc) |
  101. @  |               -----             ------------------------------- |
  102. @  \                 2                               2               /
  103. @
  104. @ where amd=a-d and bmc=b-c.
  105. @
  106. @ The transforms work with complex numbers, however the on-diagonal
  107. @ results get much grosser.
  108. @
  109. @ To save matrix math the code utilizes one transform which is the
  110. @ product of the trig and hyperbolic transforms:
  111. @
  112. @ [[ cb*ca+sb*sa  cb*sa+ca*sb ]  [[a b]  [[ cb*ca-sb*sa -cb*sa-ca*sb ]
  113. @  [ cb*sa-ca*sb  cb*ca-sb*sa ]]  [c d]]  [ ca*sb-cb*sa  cb*ca+sb*sa ]]
  114. @
  115. @ where cb=COS(beta), sb=SIN(beta), ca=COSH(alpha) and sa=SINH(alpha)
  116. @  and  alpha=ATANH(bmc/amd)/2
  117. @  and  beta=ATAN((b+c)/(amd*SQRT(1-bmc/amd)*SQRT(1+bmc/amd)))/2
  118. @  and  amd=a-d and bmc=b-c.
  119. @
  120. @ (The seemingly redundant math assures that signs, etc. are correct for
  121. @ complex inputs.)
  122. @
  123. @   I had implemented the calculation of the xform matricies without
  124. @ using explicit trig and hyperbolic functions, but getting all of the
  125. @ edge conditions right is a nightmare (at least for me).  Since those
  126. @ implementations only sped up the aggragate algorithm by only 2-3% I
  127. @ opted for simplicity.
  128. @
  129. @ Known limitations:
  130. @   Defective matricies cannot be eigenvalue/eigenvector decomposed.
  131. @     Hence, this and any other implementations are doomed in the general
  132. @     case.  (See ref 2 pages 353... for an explanation.)
  133. @
  134. @   Although it would be nice, I do not yet perform orthogonalization of
  135. @     the resultant eigenvectors, so matricies with repeated eigenvalues
  136. @     usualy do not yield orthogonal eigenvectors.
  137. @
  138. @   If the input matrix is Real Symmetric, I still use complex math.
  139. @     There is a posibility that roundoff errors will cause complex
  140. @     numbers to spontainiously errupt causing an error if I were to
  141. @     try to stuff them into a real array.  Try example matrix H.
  142. @     It would be nice to take advantage of real only math to speed
  143. @     up the algorithm.
  144. @
  145. @   Certain input matricies will contain values which will cause the trig
  146. @     xform to attempt to evaluate ATAN(i) or the hyperbolic xform to
  147. @     evaluate ATANH(1).  This indicates that no possible rotation will
  148. @     work in that context.  Since no rotation will work, I do no
  149. @     rotation.  If no other rotation happens before we get back to this
  150. @     same position on the next pass, we won't converge.  Example matrix
  151. @     C exibits this problem during the first pass when rotating at
  152. @     position 1, 2.
  153. @
  154. @ Suspected problems:
  155. @   The test for termination is a hack:  I quit when ABS(M) is not much
  156. @     different than ABS(diag(M)), it seems to work fine.
  157. @
  158. @
  159. @ References:
  160. @
  161. @ 1)  Matrix Computations, 2nd Edition, 1989
  162. @     Golub, Gene H. and Van Loan, Charles F.
  163. @     The John Hopkins University Press
  164. @     701 West 40th Street
  165. @     Baltimore, Maryland  21211
  166. @     ISBN 0-8018-3772-3
  167. @     ISBN 0-8018-3772-1 (pbk.)
  168. @
  169. @ 2)  Numerical Recipes (in C, Fortran or Pascal)
  170. @       The Art of Scientific Computing
  171. @     Press, William H., Flannery, Brian P.,
  172. @       Teukolsky, Saul A. and Vetterling, William T.
  173. @     Cambridge University Press
  174. @     510 North Avenue
  175. @     New Rochelle, NY  10801
  176. @     ISBN 0-521-35465-X
  177. @
  178. @ 3)  Linear Algebra, vol. II of Handbook for Automatic Computation, 1971
  179. @     Wilkinson, J.H. and Reinsch, C.
  180. @     Springer-Verlag
  181. @     New York
  182.  
  183. DIR
  184. Eigen
  185.   \<<
  186.     1 IF FS? THEN CLLCD END               @ Nuke this line for no display
  187.     RCLF SWAP -55 SF -21 CF -22 SF
  188.     DUP RE SWAP IM R\->C
  189.     DUP IDN SWAP DUP SIZE 1 GET \-> d
  190.     \<<
  191.       DO
  192.         1 d 1 -
  193.         FOR i
  194.           i 1 + d
  195.           FOR j
  196.             1 IF FS? THEN DUP 1 DISP END  @ Nuke this line for no display
  197.             DUP i j 2 \->LIST GET
  198.             OVER j i 2 \->LIST GET
  199.             DUP2 + ROT ROT -
  200.             3 PICK i DUP 2 \->LIST GET
  201.             4 PICK j DUP 2 \->LIST GET -
  202.             SWAP OVER IFERR / THEN 0 END ROT ROT
  203.             1 4 PICK DUP2 + \v/
  204.             ROT ROT - \v/ * * IFERR / THEN 0 END ATAN 2 /
  205.             IF DUP ABS 8 > THEN DROP 0 END
  206.             DUP COS SWAP SIN ROT ATANH 2 /
  207.             IF DUP ABS 8 > THEN DROP 0 END
  208.             DUP COSH SWAP SINH
  209.             5 PICK IDN DUP \-> T TT
  210.             \<<
  211.               4 DUPN
  212.               SWAP 4 ROLL * SWAP ROT * DUP2 + DUP
  213.               'T(i,i)' STO
  214.               'TT(j,j)' STO
  215.               - DUP
  216.               'T(j,j)' STO
  217.               'TT(i,i)' STO
  218.               4 ROLL * SWAP ROT * DUP2 + DUP
  219.               'T(i,j)' STO
  220.               NEG 'TT(i,j)' STO
  221.               - DUP
  222.               'T(j,i)' STO
  223.               NEG 'TT(j,i)' STO
  224.               T ROT * T ROT * TT *
  225.             \>>
  226.           NEXT
  227.         NEXT
  228.       UNTIL 0
  229.         1 d
  230.         FOR i
  231.           OVER { i i } GET DUP CONJ * RE +
  232.         NEXT \v/
  233.         OVER ABS %CH ABS .000000001 \<=
  234.       END
  235.       1 d
  236.       FOR i
  237.         DUP i DUP 2 \->LIST GET SWAP
  238.       NEXT DROP
  239.       d \->ARRY
  240.     \>> ROT STOF
  241.   \>>
  242. EFn1                             @ Apply function to arbitrary matrix
  243.   \<< SWAP Eigen ROT EFn2 \>>
  244. EFn2                             @ Apply function f to decomposed matrix
  245.   \<< \-> v f                    @ If M=V*D*V^-1, F(M) is V*F(D)*V^-1
  246.     \<< DUP 0 CON
  247.       1 OVER SIZE 1 GET          @ Loop over the elements of D
  248.       FOR i
  249.         { i i } v i GET          @ Eval f at each element of D
  250.         f EVAL PUT               @ And build F(D)
  251.       NEXT OVER / SWAP *         @ Do V*F(D)*V^-1
  252.     \>>
  253.   \>>
  254. Tst                              @ Check Eigen(M) three ways
  255.   \<<
  256.     DUP Eigen DUP SIZE 1 GET
  257.     \-> M T D d
  258.     \<< 1 d                      @ Test Eigenvalues by doing DET(M-v*I)
  259.       FOR i                      @   for each eigenvalue v
  260.         M DUP IDN D i GET * - DET
  261.       NEXT
  262.       d \->ARRY ABS "Det" \->TAG
  263.       T DUP TRN CONJ * DUP IDN - @ Check orthogonality of eigenvectors
  264.       ABS "Orth" \->TAG          @ with ABS of DOT of all pairings
  265.       M T D \<< \>> EFn2 - ABS   @ Check eigenvectors with
  266.       "Res" \->TAG 3 \->LIST     @ ABS(M - V * [v] * INV(V))
  267.     \>>
  268.   \>>
  269. Tst1                             @ Test by calculating SIN(M)^2+COS(M)^2
  270.   \<<                            @ for a random matrix M.  The result
  271.     RAND RAND RAND RAND RAND     @ should be close to the identity
  272.     RAND RAND RAND RAND          @ matrix.
  273.     { 3 3 } \->ARRY
  274.     RAND RAND RAND RAND RAND
  275.     RAND RAND RAND RAND
  276.     { 3 3 } \->ARRY R\->C
  277.     DUP Eigen DUP2
  278.     \<< SIN \>> EFn2 DUP *
  279.     ROT ROT
  280.     \<< COS \>> EFn2 DUP * +
  281.   \>>
  282. I
  283.   [[ 1 0 0 ]
  284.    [ 0 1 0 ]
  285.    [ 0 0 1 ]]
  286. A
  287.   [[ 1 2 3 ]       @ 11/3-2*SQRT(133)*SIN(ATAN(433*SQRT(3)/117)/3)/3
  288.    [ 2 4 5 ]       @ 11/3+2*SQRT(133)*SIN(ATAN(433*SQRT(3)/117)/3+pi/3)/3
  289.    [ 3 5 6 ]]      @ 11/3-2*SQRT(133)*COS(ATAN(433*SQRT(3)/117)/3+pi/6)/3
  290. B
  291.   [[  2  0  3 ]    @ Exact eigenvalues are 0, 2 and 5
  292.    [ -1 -1 -3 ]
  293.    [  1  3  6 ]]
  294. C
  295.   [[ 1  0 .01 ]    @ Eigenvalues are 11/10
  296.    [ .1 1 0 ]      @                 19/20-SQRT(3)*i/20
  297.    [ 0  1 1 ]]     @                 19/20+SQRT(3)*i/20
  298. D
  299.   [[ -261 209  -49]  @ Eigenvalues are 3, 4 and 10
  300.    [ -530 422  -98]
  301.    [ -800 631 -144]]
  302. E
  303.   [[ (1,1) (0,0) (.01,.01) ]   @ Eigenvalues are (11/10)*(1+i)
  304.    [ (.1,.1) (1,1) (0,0) ]     @             (19/20-SQRT(3)*i/20)*(1+i)
  305.    [ (0,0) (1,1) (1,1) ]]      @             (19/20+SQRT(3)*i/20)*(1+i)
  306. F
  307.   [[ (0,5) (1,2) (2,3) (-3,6) (6,0) ]
  308.    [ (-1,2) (0,6) (4,5) (-3,-2) (5,0) ]
  309.    [ (-2,3) (-4,5) (0,7) (3,0) (2,0) ]
  310.    [ (3,6) (3,-2) (-3,0) (0,-5) (2,1) ]
  311.    [ (-6,0) (-5,0) (-2,0) (-2,1) (0,2) ]]
  312. G
  313.   [[ 1 2 0 0 ]
  314.    [ 2 3 4 0 ]
  315.    [ 0 4 5 6 ]
  316.    [ 0 0 6 7 ]]
  317. H
  318.   [[ -4 1 1 1 ]     @ Eigenvalues are 1, 5, 5 and 5
  319.    [ 1 -4 1 1 ]
  320.    [ 1 1 -4 1 ]
  321.    [ 1 1 1 -4 ]]
  322. J
  323.   [[ 1 -1 0 0 ]
  324.    [ -1 2 -1 0 ]
  325.    [ 0 -1 3 -1 ]
  326.    [ 0 0 -1 4 ]]
  327. END
  328.  
  329. @ Ted A Smith
  330. @ PO Box 6308
  331. @ Longmont CO 80501
  332. @ H) (303)651-2092
  333. @ W) (303)665-5492
  334. @ Jul 20, 1991
  335. @ akcs.tasmith@@hpcvbbs.hp.cv.com
  336.